import pandas as pd
import numpy as np
import jieba
import cv2 as cv
from matplotlib import pyplot as plt
from wordcloud import WordCloud
from sklearn.feature_extraction.text import TfidfVectorizer,CountVectorizer
import pymysql

def pre_process(df):
    """
    数据预处理函数
    :param df:DataFrame类型
    :return:df
    """
    # 将性别为男的数据去除
    df.query('sex != "男"',inplace=True)
    x = df.copy()
    x.loc[:,'shortnote'] = x.loc[:,'shortnote'].apply(lambda x:x.strip())

    return x

def word_cloud(df):
    """
    求偶宣言词云图
    :param df: DataFrame类型
    :return:df
    """
    shortnote_list = df['shortnote'].tolist()
    pro_shortnote_list = [' '.join(list(jieba.cut(i))) for i in shortnote_list]
    cut_text = ' '.join(pro_shortnote_list)


    # 读入图片背景
    # 对于中文词云首先使用jieba来中文分词，然后还要记得指定font_path设置字体识别
    # 想要的话还能设置词云的背景图片
    #
    background_image = cv.imread(r'../static/images/love.jpeg')  # 设置词云形状 默认为矩形
    # 排除无用的词汇 将一些常用的动词、谓语、状语去除 只需要形容词
    exclude = ['我','的','着','在','有','和'
        ,'人','我们','这里','而','能','也',
        '可以','一直','没有','请','很','这个','哪些'
        ,'说','想','需要','到','为','已经','是因为'
        ,'什么','还是','时候','你','是','就','把',
        '一个','会','了','那个','那么','还','她','都',
        '不','他','不是','更','自己','应该','对','要','看'
        ,'你们','两个','希望','来','到','只要','为了','不要'
        ,'让','找','多','吧','哪些','给','呢','但','没','个',
        '无','做','一下','还有','如果','过','中','当做','一点']

    word_cloud = WordCloud(font_path="C:/Windows/Fonts/simfang.ttf",collocations=False,mask=background_image,
                           background_color='#fef8ef',scale=1.2,stopwords=exclude,max_font_size=180,min_font_size=15).generate(cut_text)
    plt.figure(figsize=(10, 10))
    plt.imshow(word_cloud, interpolation="bilinear")
    plt.axis("off")
    plt.savefig(r'../static/images/wordCount.jpg')
    plt.show()

def education_level_count(df):
    """
    不同学历的女性数量
    :param df: DataFrame类型
    :return:df
    """
    # 对学历进行分组
    grouped = df.groupby('education')['uid'].count().reset_index()

    # 修改列索引名称 把uid改成count
    grouped.rename(columns={'uid':'count'},inplace=True)

    # 构造列表嵌套列表的形式 方便后续批量插入到mysql数据库中
    data = [[i['education'],i['count']] for i in grouped.to_dict(orient='records')]

    print(data)
    return data

def area_count(df):
    """
    不同地区的女性数量
    :param df: DataFrame类型
    :return:df
    """
    # 对工作场所进行分组
    grouped = df.groupby('work_location')['uid'].count().reset_index()

    # 修改列索引名称 把uid改成count
    grouped.rename(columns={'uid':'count'},inplace=True)

    # 构造列表嵌套列表的形式 方便后续批量插入到mysql数据库中
    data = [[i['work_location'],i['count']] for i in grouped.to_dict(orient='records')]

    print(data)
    return data

def marry_status(df):
    """
    女性的婚姻状况
    :param df: DataFrame类型
    :return: df
    """
    # 对婚姻状况进行分组
    grouped = df.groupby('marriage')['uid'].count().reset_index()

    # 修改列索引名称 把uid改成count
    grouped.rename(columns={'uid': 'count'}, inplace=True)

    # 构造列表嵌套列表的形式 方便后续批量插入到mysql数据库中
    data = [[i['marriage'],i['count']] for i in grouped.to_dict(orient='records')]

    print(data)
    return data

def height_area_count(df):
    """
    不同身高区间的女性数量
    :param df: DataFrame类型
    :return: df
    """
    # 对身高划分区间
    low = df['height'].apply(lambda x:'<160' if x <160 else np.nan).dropna()
    medium = df['height'].apply(lambda x:'160~170' if all((x>=160,x<170)) else np.nan).dropna()
    heigh = df['height'].apply(lambda x:'170~180' if all((x>=170,x<=180)) else np.nan).dropna()

    # 合并身高区间
    height_area = pd.concat([low,medium,heigh])
    grouped = height_area.groupby(height_area).count()

    data = [[k,v] for k,v in grouped.to_dict().items()]
    print(data)
    return data

def age_area_count(df):
    """
    不同年龄区间的女性数量
    :param df: DataFrame类型
    :return: df
    """
    # 对年龄划分区间
    one = df['age'].apply(lambda x:'20~30' if all((x>=20,x<30)) else np.nan).dropna()
    two = df['age'].apply(lambda x:'30~40' if all((x>=30,x<=40)) else np.nan).dropna()
    three = df['age'].apply(lambda x:'>40' if x>40 else np.nan).dropna()

    # 合并年龄区间
    age_area = pd.concat([one,two,three])
    grouped = age_area.groupby(age_area).count()

    data = [[k,v] for k,v in grouped.items()]
    print(data)
    return data


def save_to_mysql(cursor,sql,data):
    result = cursor.executemany(sql,data)
    if result:
        print('插入成功')




if __name__ == '__main__':
    # 读取xlsx文件
    df = pd.read_excel('./jiayuan.xlsx',engine='openpyxl')
    print(df.head())
    print(df.info())

    # 对数据进行预处理
    df = pre_process(df)

    # 生成词云图
    word_cloud(df)
    raise Exception
    # 不同学历的女性数量
    data1 = education_level_count(df)

    # 不同地区的女性数量
    data2 = area_count(df)

    # 不同身高区间的女性数量
    data3 = height_area_count(df)

    # 不同年龄区间的女性数量
    data4 = age_area_count(df)

    # mysql存储数据
    conn = pymysql.Connect(host='localhost',user='root',password='123456',port=3306,database='jiayuan',charset='utf8')
    with conn.cursor() as cursor:
        try:
            sql1 = 'insert into db_edu_level_count(edu_level,count) values(%s,%s)'
            sql2 = 'insert into db_area_count(area,count) values(%s,%s)'
            sql3 = 'insert into db_height_area_count(height_area,count) values(%s,%s)'
            sql4 = 'insert into db_age_area_count(age_area,count) values(%s,%s)'
            save_to_mysql(cursor,sql1,data1)
            save_to_mysql(cursor,sql2,data2)
            save_to_mysql(cursor,sql3,data3)
            save_to_mysql(cursor,sql4,data4)
            conn.commit()
        except pymysql.MySQLError as e:
            print(e)
            conn.rollback()
